package mongodb

import (
	"context"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.mongodb.org/mongo-driver/mongo/readpref"
)

type (
	MongoDB struct {
		//options mongo需要的配置
		options *Options
		//client mongo 客户端
		client *mongo.Client
		//collections Collection缓存
		collections map[string]*mongo.Collection
	}
)

func NewMongoDB(opts ...Option) *MongoDB {
	option := &Options{}
	for _, opt := range opts {
		opt(option)
	}

	return &MongoDB{
		option,
		nil,
		make(map[string]*mongo.Collection),
	}
}

//Init 初始化, 处理用户配置，生成mongo uri
func (db *MongoDB) Init(opts ...Option) error {
	for _, opt := range opts {
		opt(db.options)
	}

	uri, err := db.options.genMongoUri()
	if err != nil {
		return err
	}

	// 连接到mongo
	db.client, err = mongo.Connect(context.Background(), options.Client().ApplyURI(uri))
	if err != nil {
		return err
	}
	return nil
}

func (db *MongoDB) Start() error {
	// ping 测试连通性, 确定已经连接好
	err := db.client.Ping(context.Background(), readpref.Primary())
	if err != nil {
		return err
	}
	return nil
}

func (db *MongoDB) UnInit() error {
	db.collections = nil
	return db.client.Disconnect(context.Background())
}

func (db *MongoDB) IsInvalid() bool {
	return db.client != nil
}

func (db *MongoDB) GetCollection(name string) *mongo.Collection {
	if co, ok := db.collections[name]; ok {
		return co
	}
	co := db.client.Database(db.options.DB).Collection(name)
	db.collections[name] = co
	return co
}
